/*通讯录案例*/
#include "iostream"
#include "windows.h"
#include "string"
using namespace std;

/*定义类型*/
// 定义通讯录最大存储数量
#define MAX 1000
// 定义联系人结构体
struct Person{
    // 1、姓名
    string name;
    // 2、性别
    string m_sex;
    // 3、年龄
    int age;
    // 4、电话号码
    string m_phone;
    // 5、联系地址
    string m_address;
};
// 定义通讯录结构体（包含联系人数组和当前通讯录中联系人数量）
struct AddressBook{
    // 联系人数组
    struct Person personArray[MAX];
    // 当前通讯录中联系人数量
    int m_size;
};

/*实现方法*/
// 欢迎菜单
void ShowMenu(){
    cout << "*************************" << endl;
    cout << "***** 通讯录管理系统 *****" << endl;
    cout << "***** 1、添加联系人  *****" << endl;
    cout << "***** 2、显示联系人  *****" << endl;
    cout << "***** 3、删除联系人  *****" << endl;
    cout << "***** 4、查找联系人  *****" << endl;
    cout << "***** 5、修改联系人  *****" << endl;
    cout << "***** 6、清空联系人  *****" << endl;
    cout << "***** 0、退出通讯录  *****" << endl;
    cout << "**************************" << endl;
    cout << endl;
}
// 添加联系人
void addPerson(struct AddressBook abs[]){
    // 判断如果通讯录中联系人数量已经大于MAX，那么就提示不再添加联系人
    if(abs->m_size == MAX){
        // 提示语
        cout << "当前通讯录中联系人已达到最大值，不能再添加联系人！" << endl;
        return;
    }else{
        // 可以添加联系人
        // 姓名
        cout << "请输入联系人姓名：" << endl;
        string cin_name;
        // 接收用户输入
        // 存放数组时，用当前通讯录联系人作为下标，实时更新联系人数组
        cin >> cin_name;
        abs->personArray[abs->m_size].name = cin_name;
        // 性别
        cout << "请输入联系人性别：" << endl;
        cout << "1---男" << endl;
        cout << "2---女" << endl;
        int cin_sex = 0;

        // 判断性别是否正确，不正确一直输入下去
        while (TRUE){
            cin >> cin_sex;
            if(cin_sex == 1 || cin_sex == 2){
                // 三目运算符    cin_sex值等于2吗？ 等于2，则值为女，否则值为男
                abs->personArray[abs->m_size].m_sex = cin_sex == 2 ? "女" : "男";
                break;
            }else{
                cout << "输入错误，请重新输入！" << endl;
            }
        }
        // 年龄
        cout << "请输入联系人年龄：" << endl;
        int cin_age = 0;
        cin >> cin_age;
        abs->personArray[abs->m_size].age = cin_age;
        // 电话号码
        cout << "请输入联系人电话号码：" << endl;
        string cin_phone;
        cin >> cin_phone;
        abs->personArray[abs->m_size].m_phone = cin_phone;
        // 联系地址
        cout << "请输入联系人联系地址：" << endl;
        string cin_address;
        cin >> cin_address;
        abs->personArray[abs->m_size].m_address = cin_address;
    }
    // 完整添加联系人后，要更新当前通讯录中联系人的数量
    abs->m_size++;

    // 提示联系人添加成功
    cout << "联系人添加成功！、按任意键清屏继续..." << endl;

    // 提示按任意键清屏继续
    system("pause");
    system("cls");
}
// 显示联系人
void showPerson(struct AddressBook abs[]){
    // 先清屏
    system("cls");
    // 判断通讯录是否为空
    if (abs->m_size == 0){
        cout << "当前通讯录为空，请添加联系人！" << endl;
        system("pause");
        system("cls");
        return;
    }else{
        // 显示联系人
        for (int i = 0 ; i < abs->m_size; i++){
            cout << "姓名：" << abs->personArray[i].name << "\t";
            cout << "性别：" << abs->personArray[i].m_sex << "\t";
            cout << "年龄：" << abs->personArray[i].age << "\t";
            cout << "电话号码：" << abs->personArray[i].m_phone << "\t";
            cout << "联系地址：" << abs->personArray[i].m_address << endl;
        }
    }
    // 提示按任意键清屏继续
    cout << "所有数据已显示、按任意键清屏继续..." << endl;
    system("pause");
    system("cls");
}
// 判断联系人是否存在，存在返回联系人在通讯录中的下标，不存在返回-1
int isExist(struct AddressBook abs[], string find_name) {
    // find_name 要比对查找的联系人名称
    for (int i = 0; i < abs->m_size; ++i) {
        // 如果找到要查询的名字返回该联系人在通讯录中的下标
        if (abs->personArray[i].name == find_name) {
            return i;
        }
    }
    // 没找到该联系人，则返回-1（不可能的值）
    return -1;
}
// 删除联系人    先查找有没有，有就删除，没有就提示查无此人
void deletePerson(struct AddressBook abs[]){
    // 先查找有没有该联系人
    cout << "请输入你要删除的联系人姓名：" << endl;
    string find_name;
    cin >> find_name;
    // 获取是否找到联系人的返回值 没找到返回-1.找到返回该联系人在通讯录中的下标位置
    int get_num = isExist(abs,find_name);
    // 判断 返回的下标
    if(get_num == -1){
        cout << "查无此人！" << endl;
        system("pause");
        system("cls");
        return;
    }
    // 有下标的情况，数组后一个元素覆盖下标所在的元素（循环覆盖），并且数组总长度-1
    for (int i = 0; i < abs->m_size; ++i) {
        abs->personArray[get_num] = abs->personArray[get_num + 1];
    }
    // 通讯录数组总长度-1
    abs->m_size--;
    cout << "删除成功!" << endl;
    system("pause");
    system("cls");
}
// 查找联系人
void findPerson(struct AddressBook abs[]){
    // 先查找有没有该联系人
    cout << "请输入你要删除的联系人姓名：" << endl;
    string find_name;
    cin >> find_name;
    // 获取是否找到联系人的返回值 没找到返回-1.找到返回该联系人在通讯录中的下标位置
    int get_num = isExist(abs,find_name);
    // 判断 返回的下标
    if(get_num == -1){
        cout << "查无此人！" << endl;
        system("pause");
        system("cls");
        return;
    }
    system("cls");
    // 找到联系人姓名时，使用下标打印联系人的信息
    cout << "你查找的通讯录中的联系人：" << endl;
    cout << "姓名:" << abs->personArray[get_num].name << "\t";
    cout << "性别:" << abs->personArray[get_num].m_sex << "\t";
    cout << "年龄:" << abs->personArray[get_num].age << "\t";
    cout << "联系电话:" << abs->personArray[get_num].m_phone << "\t";
    cout << "住址:" << abs->personArray[get_num].m_address << endl;
    // 提示语，按键退出
    cout << "按任意键退出!" << endl;
    system("pause");
    system("cls");
}
// 修改联系人
void chiocePerson(struct AddressBook abs[]){
    // 查找联系人是否存在
    cout << "请输入你要修改的联系人姓名：" << endl;
    string find_name;
    cin >> find_name;
    // 先查找有没有该联系人
    int get_num = isExist(abs,find_name);
    // 判断 返回的下标
    if(get_num == -1){
        cout << "查无此人！" << endl;
        system("pause");
        system("cls");
        return;
    }
    system("cls");
    // 显示联系人信息，用于参照修改
    cout << "你修改的通讯录中的联系人：" << endl;
    cout << "姓名:" << abs->personArray[get_num].name << "\t";
    cout << "性别:" << abs->personArray[get_num].m_sex << "\t";
    cout << "年龄:" << abs->personArray[get_num].age << "\t";
    cout << "联系电话:" << abs->personArray[get_num].m_phone << "\t";
    cout << "住址:" << abs->personArray[get_num].m_address << endl;
    // 修改联系人信息
    if(abs->m_size == MAX){
        // 提示语
        cout << "当前通讯录中联系人已达到最大值，不能再添加联系人！" << endl;
        return;
    }else {
        // 可以添加联系人
        // 姓名
        cout << "请输入修改后的联系人姓名：" << endl;
        string cin_name;
        // 接收用户输入
        // 存放数组时，用当前通讯录联系人作为下标，实时更新联系人数组
        cin >> cin_name;
        abs->personArray[get_num].name = cin_name;
        // 性别
        cout << "请输入修改后的联系人性别：" << endl;
        cout << "1---男" << endl;
        cout << "2---女" << endl;
        int cin_sex = 0;

        // 判断性别是否正确，不正确一直输入下去
        while (TRUE) {
            cin >> cin_sex;
            if (cin_sex == 1 || cin_sex == 2) {
                // 三目运算符    cin_sex值等于2吗？ 等于2，则值为女，否则值为男
                abs->personArray[get_num].m_sex = cin_sex == 2 ? "女" : "男";
                break;
            } else {
                cout << "输入错误，请重新输入！" << endl;
            }
        }
        // 年龄
        cout << "请输入修改后的联系人年龄：" << endl;
        int cin_age = 0;
        cin >> cin_age;
        abs->personArray[get_num].age = cin_age;
        // 电话号码
        cout << "请输入修改后的联系人电话号码：" << endl;
        string cin_phone;
        cin >> cin_phone;
        abs->personArray[get_num].m_phone = cin_phone;
        // 联系地址
        cout << "请输入修改后的联系人联系地址：" << endl;
        string cin_address;
        cin >> cin_address;
        abs->personArray[get_num].m_address = cin_address;
    }
    // 打印提示信息，退出函数
    cout << "联系人信息已修改，按任意键退出!" << endl;
    system("pause");
    system("cls");
}
// 清空通讯录    将通讯录长度清零即可
void clearAddressBook(struct AddressBook abs[]){
    // 通讯录当前联系人数组长度清零
    abs->m_size = 0;
    cout << "通讯录已清空！" << endl;
    system("pause");
    system("cls");
}

int main() {
    // 引入（windows.h）设置中文字符编码：UTF-8
    SetConsoleOutputCP(CP_UTF8);
    // 解决system("pause"); 输入出现乱码
    system("chcp 65001");

    // 数据准备
    // 初始化通讯录结构体，并且初始化当前通讯录中联系人数量
    AddressBook abs;
    abs.m_size = 0;

    // 初始准备两个数据
    {
        //  数据一、
        abs.personArray[abs.m_size].name = "屮猫";
        abs.personArray[abs.m_size].m_sex = "女";
        abs.personArray[abs.m_size].age = 18;
        abs.personArray[abs.m_size].m_phone = "13278216873";
        abs.personArray[abs.m_size].m_address = "家里蹲";
        abs.m_size++;
        // 数据二、
        abs.personArray[abs.m_size].name = "金刚";
        abs.personArray[abs.m_size].m_sex = "男";
        abs.personArray[abs.m_size].age = 88;
        abs.personArray[abs.m_size].m_phone = "12345678900";
        abs.personArray[abs.m_size].m_address = "夺命岛";
        abs.m_size++;
    }

    // 用户选择
    int chioce = 0;

    // 无限循环，处理用户输入
    while(TRUE){
        // 显示菜单
        ShowMenu();
        // 提示信息
        cout << "请输入你的选择：";
        // 接收用户输入
        cin >> chioce;
        switch (chioce) {
            case 1:     // 1、添加联系人
                // 结构体名不是地址，所以要加&符号，才能传地址给方法
                addPerson(&abs);
                break;
            case 2:     // 2、显示联系人
                showPerson(&abs);
                break;
            case 3:     // 3、删除联系人
                deletePerson(&abs);
                break;
            case 4:     // 4、查找联系人
//                {
//                    // switch的case子语句中，代码行数超过七行就会报错，可以使用大括号减少代码行数
//                    int get_num = -1;
//                    string get_name;
//                    cout << "请输入联系人姓名" << endl;
//                    cin >> get_name;
//                    get_num = isExist(&abs,get_name);
//                    cout << get_num << endl;
//                    system("pause");
//                    system("cls");
//                }
                findPerson(&abs);
                break;
            case 5:     // 5、修改联系人
                chiocePerson(&abs);
                break;
            case 6:     // 6、清空联系人
                clearAddressBook(&abs);
                break;
            case 0:     // 0、退出通讯录
                cout << "系统已退出..." << endl;
                exit(0);
            default:
                cout << "只能选择0~6之间的数字，请重新输入" << endl;
        }
    }
}